package com.explorati.interview.interview.Thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class PrintABCUsingLockCondition {

	int times;
	int state;
	Lock lock = new ReentrantLock();
	private Condition cA = lock.newCondition();
	private Condition cB = lock.newCondition();
	private Condition cC = lock.newCondition();

	public PrintABCUsingLockCondition(int times) {
		this.times = times;
	}

	public void printA() {
		print("A", 0, cA, cB);
	}

	public void printB() {
		print("B", 1, cB, cC);
	}

	public void printC() {
		print("C", 2, cC, cA);
	}

	private void print(String name, int targetState, Condition current, Condition next) {
		lock.lock();
		try {
			for(int i = 0; i < times; ){
				while (state % 3 != targetState) {
					current.await();
				}
				state++;
				i++;
				System.out.print(name);
				next.signal();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public static void main(String[] args) {
		PrintABCUsingLockCondition printABCUsingLockCondition = new PrintABCUsingLockCondition(10);
		new Thread(() -> {
			printABCUsingLockCondition.printA();
		}).start();
		new Thread(() -> {
			printABCUsingLockCondition.printB();
		}).start();
		new Thread(() -> {
			printABCUsingLockCondition.printC();
		}).start();
	}
}
